# app.py
import os
import json
import logging
from gui import GUI
from ChatState import ChatState
from websocket_client import WebSocketClient
import asyncio
import threading

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 单例装饰器
def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class App:
    def __init__(self, url: str = "wss://api.tenclass.net/xiaozhi/v1/", token: str = "test-token"):
        self.gui = None
        self.ws_client = None
        self.chat_state = ChatState()  # 聊天状态缓存
        self.ws_url = url
        self.token = token
        self.Protocol_Version = 3
        self.dev_mac_id = "f0:9e:9e:0e:ac:ac"
        self.loop = asyncio.get_event_loop()  # 添加 loop 属性

    def start(self):
        # 启动界面
        if self.gui is None:
            self.gui = GUI(self.on_button_click, self.handle_message)
            self.gui.run()
        else:
            print("App already running!")

    def handle_message(self, message):
        """处理从 WebSocket 接收到的消息"""
        logger.info(f"Received message: {message}")
        # 在这里处理消息，例如更新 GUI 或其他操作
        self.gui.update_text(message)
    
    def on_button_click(self):
        """当唤醒按钮被点击时，执行以下内容"""
        self.gui.update_text("点击")
        logger.info("唤醒按钮被点击")
        
        # 创建线程
        thread = threading.Thread(target=self.thread_dialogue)
        thread.start()# 启动线程
        
    def thread_dialogue(self):
        
        # 创建
        ws_c = WebSocketClient(self.ws_url, self.token, self.dev_mac_id, self.Protocol_Version)
        asyncio.run(self.run_websocket(ws_c))

    async def run_websocket(self, ws_c):
        # 连接 WebSocket
        await ws_c.connect()
        
        # 运行 WebSocket 客户端
        await ws_c.run_forever()
        
        # 发送握手信息
        init_message = {
            "type": "hello",
            "transport": "websocket",
            "version": 3,
            "response_mode": "auto",
            "audio_params": {
                "format": "opus",
                "sample_rate": 16000,
                "channels": 1,
                "frame_duration": 60
            }
        }
        await ws_c.send_message(json.dumps(init_message))
        
        # 发送状态切换
        await ws_c.send_status("wake_word_detected") 

    def __del__(self):
        if self.gui:
            self.gui.root.destroy()  # 确保在删除对象时关闭 GUI 窗口
        if self.loop.is_running():
            self.loop.stop()
        self.loop.close()